#include <iostream>
#include "Acceptor.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>

using std::cout;
using std::endl;

void Acceptor::init()
{
    setReuseIp();
    setReusePort();
    bind();
    listen();
}

Acceptor::Acceptor(const char *ip, unsigned short port)
    : _sock{}, _inet{ip, port}
{
}

Acceptor::~Acceptor() {}

void Acceptor::setReuseIp()
{
    int opt = 1;
    int ret = setsockopt(_sock.fd(), SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    if (ret < 0)
    {
        perror("setsockopt");
        exit(-1);
    }
}

void Acceptor::setReusePort()
{
    int opt = 1;
    int ret = setsockopt(_sock.fd(), SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
    if (ret < 0)
    {
        perror("setReusePort");
        exit(-1);
    }
}

void Acceptor::bind()
{
    sockaddr_in addr = _inet.getInetAddress();
    int ret = ::bind(_sock.fd(), (struct sockaddr *)&addr, sizeof(addr));
    if (ret < 0)
    {
        perror("bind");
        exit(-1);
    }
}

void Acceptor::listen()
{
    int ret = ::listen(_sock.fd(), 128);
    if (ret < 0)
    {
        perror("listen");
        exit(-1);
    }
}

int Acceptor::accept()
{
    cout << "_sock.fd() = " << _sock.fd() << endl;
    int cltFd = ::accept(_sock.fd(), nullptr, nullptr);
    if (cltFd == -1)
    {
        perror("accept");
        exit(-1);
    }
    return cltFd;
}